package com.glory.erp.invoice.order.service.impl;

import java.io.Serializable;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.glory.erp.auth.base.BaseQueryModel;
import com.glory.erp.auth.emp.bean.Emp;
import com.glory.erp.exception.AppException;
import com.glory.erp.invoice.goods.bean.Goods;
import com.glory.erp.invoice.operdetail.bean.OperDetail;
import com.glory.erp.invoice.operdetail.dao.OperDetailDao;
import com.glory.erp.invoice.order.bean.Order;
import com.glory.erp.invoice.order.bean.OrderQuery;
import com.glory.erp.invoice.order.dao.OrderDao;
import com.glory.erp.invoice.order.service.OrderService;
import com.glory.erp.invoice.orderdetail.bean.OrderDetail;
import com.glory.erp.invoice.orderdetail.dao.OrderDetailDao;
import com.glory.erp.invoice.store.bean.Store;
import com.glory.erp.invoice.storedetail.bean.StoreDetail;
import com.glory.erp.invoice.storedetail.dao.StoreDetailDao;
import com.glory.erp.util.NumUtil;

public class OrderServiceImpl implements OrderService {

	private OrderDao orderDao;
	private OrderDetailDao orderDetailDao;
	private StoreDetailDao storeDetailDao;
	private OperDetailDao operDetailDao;
	
	public void setOrderDetailDao(OrderDetailDao orderDetailDao) {
		this.orderDetailDao = orderDetailDao;
	}

	public void setStoreDetailDao(StoreDetailDao storeDetailDao) {
		this.storeDetailDao = storeDetailDao;
	}

	public void setOperDetailDao(OperDetailDao operDetailDao) {
		this.operDetailDao = operDetailDao;
	}

	public void setOrderDao(OrderDao orderDao) {
		this.orderDao = orderDao;
	}

	public void save(Order order) {
		orderDao.save(order);
	}

	public void update(Order order) {
		orderDao.update(order);
	}

	public void delete(Order order) {
		orderDao.delete(order);
	}

	public Order findById(Serializable uuid) {
		return orderDao.findById(uuid);
	}

	public List<Order> findAll() {
		return orderDao.findAll();
	}

	public List<Order> findAll(BaseQueryModel qm, Integer pageNum,
			Integer pageCount) {
		return orderDao.findAll(qm, pageNum, pageCount);
	}

	public Integer getCount(BaseQueryModel qm) {
		return orderDao.getCount(qm);
	}

	public void saveBuyOrder(Order order, Long[] goodsUuids, Integer[] nums,
			Double[] prices, Emp creater) {
		 // 设置订单号 唯一
		 String orderNum = NumUtil.generatorOrderNum();
		 order.setOrderNum(orderNum);
		 // 订单创建时间是当前系统时间
		 order.setCreateTime(System.currentTimeMillis());
		 // 当前保存的是采购订单
		 order.setOrderType(Order.ORDER_ORDERTYPE_OF_BUY);
		 // 新保存的订单状态是未审核的
		 order.setType(Order.ORDER_TYPE_OF_BUY_NO_CHECK);
		 // 创建人
		 order.setCreater(creater);
		 // 对应的供应商已经在order中
		 
		 // 设置订单中对应的明细数据
		 // 初始化数量
		 Integer totalNum = 0;
		 Double totalPrice = 0.0d;
		 Set<OrderDetail> orderDetails = new HashSet<OrderDetail>();
		 for (int i = 0; i < goodsUuids.length; i++) {
			 // 创建订单明细的对象并添加到集合中
			 OrderDetail od = new OrderDetail();
			 // 设置订单明细的数量
			 od.setNum(nums[i]);
			 // 设置订单剩余未入库数量
			 od.setSurplus(nums[i]);
			 // 设置订单明细的单价
			 od.setPrice(prices[i]);
			 // 设置订单明细的商品
			 Goods g = new Goods();
			 g.setUuid(goodsUuids[i]);
			 od.setGoods(g);
			 // 设置所属的订单
			 od.setOrder(order);
			 // 将明细对象加入到集合
			 orderDetails.add(od);
			
			 totalNum += nums[i];
			 totalPrice += nums[i] * prices[i];
		 }
		 order.setOrderDetails(orderDetails);
		 // 设置总数量
		 order.setTotalNum(totalNum);
		 // 设置总价格
		 order.setTotalPrice(totalPrice);
		 orderDao.save(order);
	}

	public List<Order> findAllBuy(OrderQuery orderQuery, Integer pageNum,
			Integer pageCount) {
		// 设置一个固定的条件，订单类别为采购
		orderQuery.setOrderType(Order.ORDER_ORDERTYPE_OF_BUY);
		return orderDao.findAll(orderQuery, pageNum, pageCount);
	}

	private Integer[] buyCheckOrderTypes = new Integer[]{
		Order.ORDER_ORDERTYPE_OF_BUY,
		Order.ORDER_ORDERTYPE_OF_RETURN_BUY
		};
	
	public int getCountBuyCheck(OrderQuery orderQuery) {
		return orderDao.getCountOrderTypes(orderQuery,buyCheckOrderTypes);
	}

	public List<Order> findAllBuyCheck(OrderQuery orderQuery, Integer pageNum,
			Integer pageCount) {
		return orderDao.findAllOrderTypes(orderQuery,pageNum,pageCount,buyCheckOrderTypes);
	}

	public void buyCheckPass(Long uuid,Emp checker) {
		// 审核就是更新业务
		// 快照更新
		Order o = orderDao.findById(uuid);
		if(!o.getType().equals(Order.ORDER_TYPE_OF_BUY_NO_CHECK)){
			throw new AppException("对不起，请不要非法操作！");
		}
		// type
		o.setType(Order.ORDER_TYPE_OF_BUY_CHECK_PASS);
		// 审核人
		o.setChecker(checker);
		// 审核时间
		o.setCheckTime(System.currentTimeMillis());
	}

	public void buyCheckNoPass(Long uuid, Emp checker) {
		// 审核就是更新业务
		// 快照更新
		Order o = orderDao.findById(uuid);
		if(!o.getType().equals(Order.ORDER_TYPE_OF_BUY_NO_CHECK)){
			throw new AppException("对不起，请不要非法操作！");
		}
		// type
		o.setType(Order.ORDER_TYPE_OF_BUY_CHECK_NO_PASS);
		// 审核人
		o.setChecker(checker);
		// 审核时间
		o.setCheckTime(System.currentTimeMillis());
	}

	public Integer getCountTask(OrderQuery orderQuery) {
		return orderDao.findAllTypes(orderQuery,taskTypes);
	}

	private Integer[] taskTypes = new Integer[]{
			Order.ORDER_TYPE_OF_BUY_CHECK_PASS,
			Order.ORDER_TYPE_OF_BUY_BUYING,
			Order.ORDER_TYPE_OF_BUY_IN_STORE,
			Order.ORDER_TYPE_OF_BUY_COMPLETE
		};
	
	public List<Order> findAllTask(OrderQuery orderQuery, Integer pageNum,
			Integer pageCount) {
		// 运输任务必须是已经审核通过的
		return orderDao.findAllTypes(orderQuery, pageNum, pageCount, taskTypes);
	}

	public void assignTask(Long uuid, Emp completer) {
		Order o = orderDao.findById(uuid);
		// 集合包含行判定
		if(!o.getType().equals(Order.ORDER_TYPE_OF_BUY_CHECK_PASS)){
			throw new AppException("对不起，请不要非法操作！");
		}
		// 设置状态
		o.setType(Order.ORDER_TYPE_OF_BUY_BUYING);
		// 设置跟单人
		o.setCompleter(completer);
	}

	public Integer getCountTask(OrderQuery orderQuery, Emp login) {
		// 设置当前登录人为跟单人
		orderQuery.setCompleter(login);
		// 设置type加强程序健壮性
		return orderDao.getCount(orderQuery);
	}

	public List<Order> findAllTask(OrderQuery orderQuery, Integer pageNum,
			Integer pageCount, Emp login) {
		// 设置当前登录人为跟单人
		orderQuery.setCompleter(login);
		return orderDao.findAll(orderQuery, pageNum, pageCount);
	}

	public void endTask(Long uuid) {
		Order o = orderDao.findById(uuid);
		if(!o.getType().equals(Order.ORDER_TYPE_OF_BUY_BUYING)){
			throw new AppException("对不起，请不要非法操作！");
		}
		// 设置状态为入库中
		o.setType(Order.ORDER_TYPE_OF_BUY_IN_STORE);
	}

	public Integer getCountInStore(OrderQuery orderQuery) {
		orderQuery.setType(Order.ORDER_TYPE_OF_BUY_IN_STORE);
		return orderDao.getCount(orderQuery);
	}

	public List<Order> findAllInStore(OrderQuery orderQuery, Integer pageNum,
			Integer pageCount) {
		// 入库的数据状态必然是入库中的（采购入库中、销售退货入库中）
		orderQuery.setType(Order.ORDER_TYPE_OF_BUY_IN_STORE);
		return orderDao.findAll(orderQuery, pageNum, pageCount);
	}

	public OrderDetail inGoods(Long storeUuid, Long orderDetailUuid, Integer num,
			Emp login) {
		// 入库
		// 订单明细中的剩余数量需要更新
		OrderDetail od = orderDetailDao.findById(orderDetailUuid);
		Order o = od.getOrder();
		if(!o.getType().equals(Order.ORDER_TYPE_OF_BUY_IN_STORE)){
			throw new AppException("悟空，莫调皮！");
		}
		if(od.getSurplus() < num){
			throw new AppException("悟空，莫调皮！");
		}
		od.setSurplus(od.getSurplus()-num);
		// 商品信息需要使用
		Goods g = od.getGoods();
		Store s = new Store();
		s.setUuid(storeUuid);
		// 库存数量要发生变化
		StoreDetail sd = storeDetailDao.findByStoreAndGoods(storeUuid,g.getUuid());
		// 判断该商品在指定仓库中有没有存储过
		if(sd != null) {
			// 存储过，快照更新
			// 修改当前库存数量
			sd.setNum(sd.getNum()+num);
		} else {
			// 没有存储过，新增数据
			sd = new StoreDetail();
			sd.setNum(num);
			sd.setGoods(g);
			sd.setStore(s);
			storeDetailDao.save(sd);
		}
		// 数据要求可跟踪，记录操作日志
		OperDetail opd = new OperDetail();
		opd.setNum(num);
		opd.setOperTime(System.currentTimeMillis());
		opd.setType(OperDetail.OPER_TYPE_OF_IN);
		opd.setGoods(g);
		opd.setStore(s);
		opd.setEmp(login);
		operDetailDao.save(opd);
		// 设置订单的状态为入库完毕
		Integer sum = 0;
		for (OrderDetail temp : o.getOrderDetails()) {
			sum += temp.getSurplus();
		}
		if(sum == 0){
			// 全部入库完毕
			o.setType(Order.ORDER_TYPE_OF_BUY_COMPLETE);
			o.setEndTime(System.currentTimeMillis());
		}
		return od;
	}
}